////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    SlotProbabilityTable.cpp                                     //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 03/28/2005                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class implementation for a utility class that    //
//				 manages probability tables.                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2005 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#include "SlotProbabilityTable.h"
#include "getrand.h"

////////////////////////////////////////////////////////////////////////////
/// @fn		SlotProbabilityTable::SlotProbabilityTable( int32 nTableID )
///
/// @param  nTableID	The ID of the probability table.
///
/// This is the default constructor for the class.
////////////////////////////////////////////////////////////////////////////
SlotProbabilityTable::SlotProbabilityTable( int32 nTableID )
{
	m_nTableID = nTableID;
	m_nMaxWeightForTable = 0;
}

////////////////////////////////////////////////////////////////////////////
/// @fn		SlotProbabilityTable::addEntry( uint32 nMaxWeightForValue, int32 nValue )
///
/// @param  nMaxWeightForValue	The upper bound of the range that will pick this entry.
///								NOTE: The lower bound is always the upper bound of the
///								previous entry + 1.
/// @param	nValue				The value that is returned if the random number falls
///								in the range for this entry.
///
/// Adds an entry to the probability table.
////////////////////////////////////////////////////////////////////////////
void SlotProbabilityTable::addEntry( uint32 nMaxWeightForValue, int32 nValue )
{
	// Add a new entry to the vector using the information that was passed in.
	m_vecEntries.push_back( SlotProbabilityTableEntry( nMaxWeightForValue, nValue ) );

	// If this ASSERT fires then the entries have not been added in the correct order.
	ASSERT( nMaxWeightForValue >= m_nMaxWeightForTable );

	// Store the maximum weight for the table for later on when we need to pick
	// a random value from the table.
	m_nMaxWeightForTable = nMaxWeightForValue;
}

////////////////////////////////////////////////////////////////////////////
/// @fn		SlotProbabilityTable::getRandomValue() const
///
/// @return	int32	A random value from the probability table.
///
/// Gets a random value from the probability table.
////////////////////////////////////////////////////////////////////////////
int32 SlotProbabilityTable::getRandomValue() const
{
	// Get a random number less than our maximum weight plus one
	// (i.e. from 0 up to and including maximum weight).
	uint32 nRandom = getRandomLessThan( m_nMaxWeightForTable + 1 );

	// Loop through all of the entries.
    for ( SlotProbabilityTableEntryVector::const_iterator it = m_vecEntries.begin(); it != m_vecEntries.end(); it++ )
	{
		// If the random number falls within the range of this entry...
		if ( nRandom <= it->m_nMaxWeightForValue )
		{
			// then we have found our value.
			return it->m_nValue;
		}
	}

	// This should never happen...
	ASSERT(false);

	// ...but if it does then I guess we should just return 0.
	return 0;
}
